local addonName, addonTable = ...
local eventframe = CreateFrame("Frame")
eventframe:SetScript("OnEvent", 
function(self,event,...) 
	return self[event] and self[event](...)
end)
eventframe:RegisterEvent("ADDON_LOADED")
eventframe:RegisterEvent("PLAYER_REGEN_ENABLED")
eventframe:RegisterEvent("PLAYER_REGEN_DISABLED")
eventframe:RegisterEvent("PLAYER_ALIVE")
eventframe:RegisterEvent("GROUP_ROSTER_UPDATE") -- gone in MoP
eventframe:RegisterEvent("GROUP_JOINED")

local lastUpdate = 0
local flareAnchor, worldMarker
local timers = {}
local timersToText = {}
local FLARE_TIMER = 3600 -- 1h now?
local label = "|cff0070ddFlare|cffa335eeUP|r"

local UnitIsGroupLeader, UnitIsGroupAssistant, UnitIsRaidOfficer, IsEveryoneAssistant, InCombatLockdown, UnitAffectingCombat =
      UnitIsGroupLeader, UnitIsGroupAssistant, UnitIsRaidOfficer, IsEveryoneAssistant, InCombatLockdown, UnitAffectingCombat
local floor = math.floor
local mod = mod
local format = string.format
local GetTime = GetTime

local function InCombat()
	return (InCombatLockdown() or UnitAffectingCombat("player") or UnitAffectingCombat("pet") or eventframe.incombat)
end

local function findSide(frame)
	local side = "left";
	local rightDist = 0;
	local leftPos = frame:GetLeft();
	local rightPos = frame:GetRight();
	if ( not rightPos ) then
		rightPos = 0;
	end
	if ( not leftPos ) then
		leftPos = 0;
	end
	rightDist = GetScreenWidth() - rightPos;
	if (leftPos and (rightDist < leftPos)) then
		side = "left";
	else
		side = "right";
	end
	return side
end

local function updateTooltip()
	if flareAnchor.side == "left" then
  	GameTooltip:SetOwner(flareAnchor,"ANCHOR_CURSOR_LEFT")
  elseif flareAnchor.side == "right" then
  	GameTooltip:SetOwner(flareAnchor,"ANCHOR_CURSOR_RIGHT")
  else
  	GameTooltip:SetOwner(flareAnchor,"ANCHOR_CURSOR")
  end
 	GameTooltip:SetClampedToScreen(true)
 	GameTooltip:ClearLines()
 	GameTooltip:SetText("World Markers Menu")
 	GameTooltip:AddLine("Right-click an edge to drag",204/255,204/255,204/255,1)
 	GameTooltip:Show()
end

local fmtime = "%d:%02d"
local function formatTime(seconds)
	local minutes = floor(seconds/60)
	local sec = mod(seconds,60)
	return format(fmtime,minutes,sec)
end

local function updateTimersText()
	local now = GetTime()
	for i=1,#timersToText do
		for i=1,#timersToText do
			if timers[i] and (now < timers[i]) then
 				timersToText[i]:SetText(formatTime(timers[i] - now))
			else
				timersToText[i]:SetText("")
			end			
		end
	end
end

local function updateTimers(self, elapsed)
	if (not flareAnchor) or (not flareAnchor:IsShown()) then return end
	lastUpdate = lastUpdate + elapsed
	if lastUpdate > TOOLTIP_UPDATE_TIME then
		updateTimersText()
		lastUpdate = 0
	end
end

local function keyWatcher()
	if not eventframe.keywatcher then return end
	if eventframe.loaded then
		eventframe.loaded = nil
		eventframe.keywatcher = nil
		eventframe.clickwatcher = nil
	end
end

local function clickWatcher(frame,button)
	if not eventframe.clickwatcher then return end
	if button and button ~= "LeftButton" and button ~= "RightButton" then return end
	if button == "LeftButton" then
		if eventframe.loaded then
			timers[eventframe.loaded] = GetTime() + FLARE_TIMER
			eventframe.loaded = nil
		end
	elseif button == "RightButton" then 
		eventframe.loaded = nil
	end
	eventframe.clickwatcher = nil
	eventframe.keywatcher = nil
end

local function clearTimers(arg1)
	if FlareUPPC.showTimers then
		if arg1 and (arg1 > 0 and arg1 <= NUM_WORLD_RAID_MARKERS) then
			timers[arg1] = nil
			updateTimersText()
		else
			wipe(timers)
			updateTimersText()
		end
		eventframe.loaded = nil
		eventframe.clickwatcher = nil
		eventframe.keywatcher = nil
	end
end

local function setTimer(marker, arg2)
	if FlareUPPC.showTimers then
		eventframe.loaded = marker
		eventframe.clickwatcher = true
		eventframe.keywatcher = true
	end
end

local function setOnUpdate(flag)
	if flag then
		if not eventframe:GetScript("OnUpdate") then
			eventframe:SetScript("OnUpdate", updateTimers)
		end
		if not eventframe.hooksdone then
			hooksecurefunc("PlaceRaidMarker", setTimer)
			hooksecurefunc("ClearRaidMarker", clearTimers)
			hooksecurefunc("ToggleGameMenu", keyWatcher)
			WorldFrame:HookScript("OnMouseUp", clickWatcher)
		end
		eventframe.hooksdone = true
	else
		eventframe:SetScript("OnUpdate",nil)
	end
end

local function createFlareAnchorButton()
	local frame = CreateFrame("Frame","FlareUPAnchor",UIParent)
	frame:SetWidth(30)
	frame:SetHeight(30)
	frame:SetPoint("TOP")
	frame:SetClampedToScreen(true)
	frame:SetClampRectInsets(-1,1,1,-50)
	frame:SetBackdrop({
	bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
	edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
	tile = true, tileSize = 16, edgeSize = 16,
	insets = { left = 4, right = 4, top = 4, bottom = 4 }
	})
	frame.anchorTimer = CreateFrame("Frame",nil,frame)
	frame.anchorTimer:SetSize(35,9)
	frame.anchorTimer:SetPoint("TOPLEFT",frame,"TOPRIGHT",2,17)
	frame.anchorTimer:SetClampedToScreen(true)
	frame.anchorTimer:SetClampRectInsets(-30,30,-8,-80)
	local blueTimer = frame:CreateFontString(nil, "OVERLAY")
	blueTimer:SetFontObject("SystemFont_Tiny")
	blueTimer:SetTextColor(0,112/255,221/255)
	blueTimer:SetShadowColor(0,0,0,1)
	blueTimer:SetShadowOffset(1,-1)
	local greenTimer = frame:CreateFontString(nil, "OVERLAY")
	greenTimer:SetFontObject("SystemFont_Tiny")
	greenTimer:SetTextColor(30/255,1,0)
	greenTimer:SetShadowColor(0,0,0,1)
	greenTimer:SetShadowOffset(1,-1)
	local purpleTimer = frame:CreateFontString(nil, "OVERLAY")
	purpleTimer:SetFontObject("SystemFont_Tiny")
	purpleTimer:SetTextColor(163/255,53/255,238/255)
	purpleTimer:SetShadowColor(0,0,0,1)
	purpleTimer:SetShadowOffset(1,-1)
	local redTimer = frame:CreateFontString(nil, "OVERLAY")
	redTimer:SetFontObject("SystemFont_Tiny")
	redTimer:SetTextColor(1,32/255,32/255)
	redTimer:SetShadowColor(0,0,0,1)
	redTimer:SetShadowOffset(1,-1)
	local yellowTimer = frame:CreateFontString(nil, "OVERLAY")
	yellowTimer:SetFontObject("SystemFont_Tiny")
	yellowTimer:SetTextColor(255/255,255/255,0)
	yellowTimer:SetShadowColor(0,0,0,1)
	yellowTimer:SetShadowOffset(1,-1)
	frame.blue = blueTimer
	frame.green = greenTimer
	frame.purple = purpleTimer
	frame.red = redTimer
	frame.yellow = yellowTimer
	frame.blue:SetPoint("TOP",frame.anchorTimer,"BOTTOM",0,0)
	frame.green:SetPoint("TOP",frame.blue,"BOTTOM",0,0)
	frame.purple:SetPoint("TOP",frame.green,"BOTTOM",0,0)
	frame.red:SetPoint("TOP",frame.purple,"BOTTOM",0,0)
	frame.yellow:SetPoint("TOP",frame.red,"BOTTOM",0,0)
	timersToText[1] = frame.blue
	timersToText[2] = frame.green
	timersToText[3] = frame.purple
	timersToText[4] = frame.red
	timersToText[5] = frame.yellow
	
	frame:SetMovable()
  frame:RegisterForDrag("RightButton")
  frame:EnableMouse(true)
  frame:SetScript("OnDragStart", function(self, button) if not InCombat() then self:StartMoving() end end);
  frame:SetScript("OnDragStop", function(self) 
  	if not InCombat() then
	  	self:StopMovingOrSizing() 
	  	self.side = findSide(self)
	  	frame.anchorTimer:ClearAllPoints()
	  	if self.side == "left" then
	  		frame.anchorTimer:SetPoint("TOPRIGHT",frame,"TOPLEFT",-2,17)
	  	elseif self.side == "right" then
	  		frame.anchorTimer:SetPoint("TOPLEFT",frame,"TOPRIGHT",2,17)
	  	end
  	end
  end);
  frame:SetScript("OnEnter", updateTooltip);
  frame:SetScript("OnLeave", GameTooltip_Hide);
  frame:SetScript("OnHide", GameTooltip_Hide);
  frame:SetScript("OnShow", function(self) 
  	self.side = findSide(self); 
  	frame.anchorTimer:ClearAllPoints()
  	if self.side == "left" then
  		frame.anchorTimer:SetPoint("TOPRIGHT",frame,"TOPLEFT",-2,17)
  	elseif self.side == "right" then
  		frame.anchorTimer:SetPoint("TOPLEFT",frame,"TOPRIGHT",2,17)
  	end
  end);
  frame:Hide()
  
	return frame
end

local function anchorMarker(marker, anchor)
	if (not marker) or (not anchor) then return end
	local readycheck = CompactRaidFrameManagerDisplayFrameLeaderOptionsInitiateReadyCheck
	local rolepoll = CompactRaidFrameManagerDisplayFrameLeaderOptionsInitiateRolePoll
	if readycheck and rolepoll then
		local parentName = readycheck:GetParent():GetName()
		readycheck:SetPoint("RIGHT",rolepoll,"RIGHT",0,0)
	end
	marker:SetParent(anchor)
	marker:ClearAllPoints()
	marker:SetPoint("CENTER",anchor,"CENTER",0,0)
	marker:SetHeight(25)
	marker:SetWidth(25)
	marker:SetFrameLevel(anchor:GetFrameLevel()+1)
	marker:SetScript("OnEnter",updateTooltip)
	marker:SetScript("OnLeave",GameTooltip_Hide)
	eventframe.anchored = true
end

local function createKeybindButtons()
	if _G["FlareUPSecureClearAll"] then return end
	
	local buttonClear = CreateFrame("Button", "FlareUPSecureClearAll", UIParent, "SecureActionButtonTemplate")
	local buttonWM1 = CreateFrame("Button", "FlareUPSecureWM1", buttonClear, "SecureActionButtonTemplate")
	local buttonWM2 = CreateFrame("Button", "FlareUPSecureWM2", buttonWM1, "SecureActionButtonTemplate")
	local buttonWM3 = CreateFrame("Button", "FlareUPSecureWM3", buttonWM2, "SecureActionButtonTemplate")
	local buttonWM4 = CreateFrame("Button", "FlareUPSecureWM4", buttonWM3, "SecureActionButtonTemplate")
	local buttonWM5 = CreateFrame("Button", "FlareUPSecureWM5", buttonWM4, "SecureActionButtonTemplate")
	
	buttonClear:SetAttribute("type","worldmarker")
	buttonClear:SetAttribute("marker",0)
	buttonClear:SetAttribute("action","clear")
	
	buttonWM1:SetAttribute("type1","worldmarker")
	buttonWM1:SetAttribute("marker1",1)
	buttonWM1:SetAttribute("action1","set")
	buttonWM1:SetAttribute("type2","worldmarker")
	buttonWM1:SetAttribute("marker2",1)
	buttonWM1:SetAttribute("action2","clear")
	
	buttonWM2:SetAttribute("type1","worldmarker")
	buttonWM2:SetAttribute("marker1",2)
	buttonWM2:SetAttribute("action1","set")
	buttonWM2:SetAttribute("type2","worldmarker")
	buttonWM2:SetAttribute("marker2",2)
	buttonWM2:SetAttribute("action2","clear")
	
	buttonWM3:SetAttribute("type1","worldmarker")
	buttonWM3:SetAttribute("marker1",3)
	buttonWM3:SetAttribute("action1","set")
	buttonWM3:SetAttribute("type2","worldmarker")
	buttonWM3:SetAttribute("marker2",3)
	buttonWM3:SetAttribute("action2","clear")
	
	buttonWM4:SetAttribute("type1","worldmarker")
	buttonWM4:SetAttribute("marker1",4)
	buttonWM4:SetAttribute("action1","set")
	buttonWM4:SetAttribute("type2","worldmarker")
	buttonWM4:SetAttribute("marker2",4)
	buttonWM4:SetAttribute("action2","clear")
	
	buttonWM5:SetAttribute("type1","worldmarker")
	buttonWM5:SetAttribute("marker1",5)
	buttonWM5:SetAttribute("action1","set")
	buttonWM5:SetAttribute("type2","worldmarker")
	buttonWM5:SetAttribute("marker2",5)
	buttonWM5:SetAttribute("action2","clear")	
	
end

local function SlashHandler(command)
	if string.lower(command) == "timers" then
		if FlareUPPC.showTimers then
			FlareUPPC.showTimers = nil
			wipe(timers)
			updateTimersText()
		else
			FlareUPPC.showTimers = true
		end
		setOnUpdate(FlareUPPC.showTimers)
		DEFAULT_CHAT_FRAME:AddMessage(label..": timers="..(FlareUPPC.showTimers and "|cff00ff00ON|r" or "|cffff0000OFF|r"))
	elseif string.lower(command) == "pos" then
		if not InCombat() then
			if not flareAnchor:IsShown() then
				flareAnchor:Show()
			else
				flareAnchor:Hide()
			end
		end
	else
		DEFAULT_CHAT_FRAME:AddMessage(label..": timers="..(FlareUPPC.showTimers and "|cff00ff00ON|r" or "|cffff0000OFF|r"))
		DEFAULT_CHAT_FRAME:AddMessage("/flareup timers (toggles marker timers)")
		DEFAULT_CHAT_FRAME:AddMessage("/flareup pos (toggles the anchor for reposition)")
	end
end

function eventframe.ADDON_LOADED(...)
	local addon = ...
	if addon == addonName then

		FlareUPPC = FlareUPPC or {["showTimers"] = true}
		flareAnchor = createFlareAnchorButton()
		SlashCmdList["FLAREUP"] = SlashHandler
		SLASH_FLAREUP1 = "/flareup"
		if IsAddOnLoaded("Blizzard_CompactRaidFrames") then
			eventframe:UnregisterEvent("ADDON_LOADED")
			if not worldMarker then
				worldMarker = CompactRaidFrameManagerDisplayFrameLeaderOptionsRaidWorldMarkerButton
			end
			if InCombat() then
				eventframe.queue = "anchor"
			else
				anchorMarker(worldMarker,flareAnchor)
				createKeybindButtons()
			end
		end
	end
	if addon == "Blizzard_CompactRaidFrames" then

		if not flareAnchor then
			flareAnchor = createFlareAnchorButton()
		end
		worldMarker = CompactRaidFrameManagerDisplayFrameLeaderOptionsRaidWorldMarkerButton
		if InCombat() then
			eventframe.queue = "anchor"
		else
			anchorMarker(worldMarker,flareAnchor)
			createKeybindButtons()
		end
		eventframe:UnregisterEvent("ADDON_LOADED")
	end
end

function eventframe.PLAYER_ALIVE()
	if not IsAddOnLoaded("Blizzard_CompactRaidFrames") then
		local loaded, reason = LoadAddOn("Blizzard_CompactRaidFrames")
		if not loaded then
			print("FlareUp: ".._G["ADDON_"..reason])
		end
	end
	eventframe:RegisterEvent("PLAYER_ENTERING_WORLD")
	eventframe:UnregisterEvent("PLAYER_ALIVE")
end

function eventframe.PLAYER_REGEN_DISABLED()
	eventframe.incombat = true
end

function eventframe.PLAYER_REGEN_ENABLED()
	eventframe.incombat = nil
	if not eventframe.queue then return end
	if eventframe.queue == "anchor" then
 		anchorMarker(worldMarker,flareAnchor)
 		createKeybindButtons()
		eventframe.queue = nil
	end
	if eventframe.queue == "show" then
		flareAnchor:Show()
		eventframe.queue = nil
	end
	if eventframe.queue == "hide" then
		updateTimersText()
		flareAnchor:Hide()
		eventframe.queue = nil
	end
end

function eventframe.GROUP_JOINED()
	eventframe.GROUP_ROSTER_UPDATE()
end

function eventframe.PLAYER_ENTERING_WORLD()
	eventframe.GROUP_ROSTER_UPDATE()
end

function eventframe.GROUP_ROSTER_UPDATE()
	local inRaid = IsInRaid()
	local inParty = (not inRaid) and IsInGroup()
	if inParty or (inRaid and UnitIsGroupLeader("player") or UnitIsGroupAssistant("player") or UnitIsRaidOfficer("player") or IsEveryoneAssistant()) then
		if InCombat() then
			eventframe.queue = "show"
		else
			flareAnchor:Show()
		end
		setOnUpdate(FlareUPPC.showTimers)
	else
		if InCombat() then
			eventframe.queue = "hide"
		else
			flareAnchor:Hide()
		end
		setOnUpdate(false)
		clearTimers()
		updateTimersText()
	end
end

_G["BINDING_HEADER_FLAREUPWORLDMARKERS"]=label.." World Markers"
_G["BINDING_NAME_CLICK FlareUPSecureClearAll:LeftButton"]="Clear All Markers"
_G["BINDING_NAME_CLICK FlareUPSecureWM1:LeftButton"]="Place |cff0070ddBlue|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM2:LeftButton"]="Place |cff1eff00Green|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM3:LeftButton"]="Place |cffa335eePurple|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM4:LeftButton"]="Place |cffff2020Red|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM5:LeftButton"]="Place |cffffff00Yellow|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM1:RightButton"]="Clear |cff0070ddBlue|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM2:RightButton"]="Clear |cff1eff00Green|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM3:RightButton"]="Clear |cffa335eePurple|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM4:RightButton"]="Clear |cffff2020Red|r"
_G["BINDING_NAME_CLICK FlareUPSecureWM5:RightButton"]="Clear |cffffff00Yellow|r"


--[[
CompactRaidFrameManagerDisplayFrameLeaderOptionsRaidWorldMarkerButton
CompactRaidFrameManagerDisplayFrameLeaderOptionsInitiateReadyCheck
CompactRaidFrameManagerDisplayFrameLeaderOptionsInitiateRolePoll
]]